/* $RCSFile: DynQueryMultiple.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/CRMWrapper3/DynQueryMultiple.cs $
 * $log$
 * Revision 14 2010/08/06 19:56:32  christian.surieux
 *   Added Log to All cs files
 */

using System;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Globalization;

using CrmSdk;
using AddonNice.CRMWrapper;

// $Id: DynQueryMultiple.cs, 13+1 2010/08/06 17:56:32 christian.surieux $


namespace AddonNice.CRMWrapper 
{
    /// <summary>
    /// Adds Multiple Query Funtionnalities 
    /// </summary>
    public class DynQueryMultiple 
    {
        public bool bindable = false;

        public InternalColumnSet Columns                             =   new InternalColumnSet();
        public InternalQueryExpression   bQuery                      =   null;
        private InternalBusinessEntityCollection entityCollection    =   null;
        InternalRetrieveMultipleRequest retrieve                     =   null;

        CRMWrapperBase _wrapper = null;
        public CRMWrapperBase wrapper 
        {
            get { return _wrapper; }
        }

        /// <summary>
        /// Beware, this is the entityname, not the name Property
        /// </summary>
        string _Name = string.Empty;
        public string Name 
        {
            get { return _Name; }
        }

        public BindableList AllResultBindable() 
        {
            if (entityCollection != null) 
            {
                if ( bQuery.ColumnSet is InternalColumnSet )
                    return new BindableList(_wrapper,entityCollection,(InternalColumnSet)bQuery.ColumnSet);
                return new BindableList(_wrapper,entityCollection,null);
            }
            return null;
        }

        public InternalBusinessEntityCollection AllResults() 
        {
            return entityCollection;
        }

        /// <summary>
        /// constructor used for creation
        /// </summary>
        /// <param name="w"></param>
        /// <param name="name"></param>
        public DynQueryMultiple(CRMWrapperBase w, string name) 
        {
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]DynQueryMultiple Constructor with name '{0}'", name),CRMTraceSwitch.Sw.Info);
            _Name       =   name;
            _wrapper    =   w;
        }

        /// <summary>
        /// constructor used for creation
        /// </summary>
        /// <param name="w"></param>
        /// <param name="name"></param>
        public DynQueryMultiple(CRMWrapperBase w) 
        {
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( "[V]DynQueryMultiple untyped constructor",CRMTraceSwitch.Sw.Info);
            _wrapper = w;
        }


        /// <summary>
        /// Retrieve dynamically with the EntityID set on constructor
        /// </summary>
        /// <returns></returns>
        public bool Retrieve(InternalQueryExpression query) 
        {
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]DynQueryMultiple Retrieve Name: {0}", Name),CRMTraceSwitch.Sw.Info);
            return internalRetrieve(query, false);
        }

        /// <summary>
        /// Retrieve dynamically with admin account the EntityID set on constructor
        /// </summary>
        /// <returns></returns>
        public bool adminRetrieve(InternalQueryExpression query) 
        {
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( "[V]DynQueryMultiple adminRetrieve with query ",CRMTraceSwitch.Sw.Info);
            return internalRetrieve(query, true);
        }


        /// <summary>
        /// Retrieve dynamically with the EntityID set on constructor
        /// </summary>
        /// <returns></returns>
        public bool Retrieve() 
        {
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]DynQueryMultiple Retrieve : building query for :: Name: {0}", Name),CRMTraceSwitch.Sw.Info);
            return internalRetrieve(null, false);
        }

        /// <summary>
        /// Retrieve dynamically with admin account the EntityID set on constructor
        /// </summary>
        /// <returns></returns>
        public bool adminRetrieve() 
        {
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]DynQueryMultiple AdminRetrieve : building query for :: Name: {0}", Name),CRMTraceSwitch.Sw.Info);
            return internalRetrieve(null, true);
        }

        private bool internalRetrieve(InternalQueryExpression query, bool isAdmin) 
        {
            //don't pollute with older results when class i reused
            entityCollection = null;
            if ( query == null) 
            {
                query = new InternalQueryExpression();
            }
            bQuery          =   query;
            // Set the properties of the target.
            if ( Columns.Attributes != null && Columns.Attributes.Length > 0) 
            {
                if ( CRMTraceSwitch.Sw.TraceVerbose )
                    Trace.WriteLine( "[V]DynQueryMultiple internalRetrieve column set given",CRMTraceSwitch.Sw.Info);
                bQuery.ColumnSet = Columns;
            } 
            else 
            {
                bQuery.ColumnSet = new InternalAllColumns();
                if ( CRMTraceSwitch.Sw.TraceVerbose )
                    Trace.WriteLine( "[V]DynQueryMultiple internalRetrieve taking all columns",CRMTraceSwitch.Sw.Info);
            }
            if ( bQuery.EntityName == String.Empty ) 
            {
                bQuery.EntityName            = Name;
            }
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]DynQueryMultiple querying entity {0}", query.EntityName),CRMTraceSwitch.Sw.Info);

            retrieve                             = wrapper.MakeRetrieveMultipleRequest(bQuery,true);

            InternalResponse retrieved = null;
            try 
            {
                if (isAdmin)
                    retrieved = wrapper.adminExecute(retrieve);
                else
                    retrieved = wrapper.userExecute(retrieve);
            } 
            catch (Exception ex) 
            {
                if ( CRMTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]DynQueryMultiple internalRetrieve ex: {0}", ex),CRMTraceSwitch.Sw.Info);
                throw;
            }
            // Extract the DynamicEntity from the request.
            int count   =   0;
            entityCollection = wrapper.Util.ExtractBusinessCollection(retrieved,ref count);
            return (count > 0);
        }

    }
}
